major update
-added support for building with ninja and added corresponding shell scripts -added EntityView class to iterate over entities of the same tag -entities are now grouped together in memory by tag rather than all together -moved globals.h into utility.h -moved EntityTag and EntityIndex into utility.h
This commit is contained in:
parent
abf26355dd
commit
260d2ad84d
|
|
@ -382,3 +382,5 @@ Makefile
|
|||
*.o
|
||||
|
||||
*.d
|
||||
|
||||
*.ninja*
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BackendCodeEditorSettings">
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MakefileSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<MakefileProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="version" value="2" />
|
||||
</MakefileProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
<component name="MakefileWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#! /bin/bash
|
||||
|
||||
./vendor/premake5/premake5 ecc
|
||||
./vendor/premake5/premake5 ninja
|
||||
ninja $1
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#! /bin/bash
|
||||
if [ -z "$1" ] || [ $# -eq 0 ]
|
||||
then
|
||||
ninja debug -t clean && ninja release -t clean
|
||||
else
|
||||
ninja $1 -t clean
|
||||
fi
|
||||
|
|
@ -6,3 +6,4 @@
|
|||
#include <Entities/Entity.h>
|
||||
#include <Entities/EntityManager.h>
|
||||
#include <Entities/EntityMemoryPool.h>
|
||||
#include <Entities/EntityView.h>
|
||||
|
|
@ -3,8 +3,6 @@
|
|||
//#include <tuple>
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/System/Angle.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
|
||||
class Component
|
||||
{
|
||||
|
|
@ -15,18 +13,14 @@ public:
|
|||
|
||||
class Transform : public Component
|
||||
{
|
||||
//potential optimization - remove angle variable
|
||||
//added time for calculations but possible speed increase from cache freindliness
|
||||
public:
|
||||
sf::Vector2f position{};
|
||||
float speed{};
|
||||
sf::Angle facing{};
|
||||
sf::Vector2f speed{};
|
||||
|
||||
Transform() = default;
|
||||
Transform(sf::Vector2f position_in, float speed_in, sf::Angle facing_in)
|
||||
Transform(sf::Vector2f position_in, sf::Vector2f speed_in)
|
||||
: position(position_in)
|
||||
, speed(speed_in)
|
||||
, facing(facing_in)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,25 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
//#include <utility.h>
|
||||
|
||||
using EntityIndex = uint16_t;
|
||||
|
||||
enum EntityTag : uint8_t
|
||||
{
|
||||
none,
|
||||
|
||||
tagCount
|
||||
};
|
||||
|
||||
#include <utility.h>
|
||||
|
||||
class EntityManager;
|
||||
class EntityViewIterator;
|
||||
class EntityViewConstIterator;
|
||||
|
||||
class Entity
|
||||
{
|
||||
private:
|
||||
//private:
|
||||
public:
|
||||
friend class EntityManager;
|
||||
Entity();
|
||||
friend class EntityViewIterator;
|
||||
friend class EntityViewConstIterator;
|
||||
|
||||
Entity() = delete;
|
||||
Entity(EntityIndex);
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
|
|
@ -34,6 +30,8 @@ public:
|
|||
template<typename T>
|
||||
void addComponent(const T&&);
|
||||
|
||||
EntityIndex id() const;
|
||||
|
||||
EntityTag tag() const;
|
||||
|
||||
bool isAlive() const;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "Entities/Entity.h"
|
||||
#include "Entities/EntityView.h"
|
||||
#include "utility.h"
|
||||
#include <Entities/EntityMemoryPool.h>
|
||||
#include <array>
|
||||
|
||||
class EntityManager
|
||||
{
|
||||
private:
|
||||
EntityView getEntiites(EntityTag);
|
||||
|
||||
inline Entity player();
|
||||
private:
|
||||
Entity m_player{0};
|
||||
std::array<u16, tagCount> m_numEntitiesByTag{};
|
||||
u16 m_numEntities{};
|
||||
};
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -20,8 +19,6 @@ private:
|
|||
ComponentVectorTuple m_components;
|
||||
std::vector<EntityTag> m_tags;
|
||||
std::vector<bool> m_aliveStates;
|
||||
size_t m_entityCount; // for debugging purposes, should not be included in release version
|
||||
bool m_holePresent{false};
|
||||
|
||||
private:
|
||||
EntityMemoryPool();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "utility.h"
|
||||
#include <Entities/Entity.h>
|
||||
|
||||
class EntityView;
|
||||
|
||||
class EntityViewIterator
|
||||
{
|
||||
friend class EntityView;
|
||||
|
||||
EntityViewIterator(EntityIndex);
|
||||
|
||||
EntityViewIterator& operator++();
|
||||
|
||||
EntityViewIterator operator++(int);
|
||||
|
||||
EntityViewIterator& operator--();
|
||||
|
||||
EntityViewIterator operator--(int);
|
||||
|
||||
Entity operator*();
|
||||
|
||||
Entity operator[](int);
|
||||
Entity* operator->();
|
||||
|
||||
bool operator==(EntityViewIterator);
|
||||
bool operator!=(EntityViewIterator);
|
||||
|
||||
private:
|
||||
Entity m_currentEntity;
|
||||
};
|
||||
|
||||
class EntityViewConstIterator
|
||||
{
|
||||
friend class EntityView;
|
||||
|
||||
EntityViewConstIterator(EntityIndex index);
|
||||
|
||||
EntityViewConstIterator& operator++();
|
||||
|
||||
EntityViewConstIterator operator++(int);
|
||||
|
||||
EntityViewConstIterator& operator--();
|
||||
|
||||
EntityViewConstIterator operator--(int);
|
||||
|
||||
const Entity operator*();
|
||||
|
||||
const Entity operator[](int index);
|
||||
|
||||
const Entity* operator->();
|
||||
|
||||
|
||||
bool operator==(EntityViewConstIterator);
|
||||
bool operator!=(EntityViewConstIterator);
|
||||
|
||||
private:
|
||||
Entity m_currentEntity;
|
||||
};
|
||||
|
||||
class EntityView
|
||||
{
|
||||
public:
|
||||
friend class EntityManager;
|
||||
EntityView() = delete;
|
||||
EntityView(EntityIndex, EntityIndex);
|
||||
|
||||
using iterator = EntityViewIterator;
|
||||
using const_iterator = EntityViewConstIterator;
|
||||
|
||||
iterator begin() { return iterator(m_start); }
|
||||
iterator end() { return iterator(m_start + m_size); }
|
||||
|
||||
|
||||
|
||||
const_iterator cbegin() const { return const_iterator(m_start); }
|
||||
const_iterator cend() const { return const_iterator(m_start + m_size); }
|
||||
private:
|
||||
EntityIndex m_start;
|
||||
EntityIndex m_size;
|
||||
};
|
||||
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#pragma once
|
||||
#include <cstddef>
|
||||
|
||||
namespace Global
|
||||
{
|
||||
inline constexpr size_t MAX_ENTITIES {10'000u};
|
||||
}
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Globals.h"
|
||||
#include <Entities/Entity.h>
|
||||
#include <SwapBackVectorIterator.hpp>
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
template<typename T, EntityIndex capacity_in = Global::MAX_ENTITIES>
|
||||
class SwapBackVector
|
||||
{
|
||||
public:
|
||||
//iterator typedefs
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using data_type = T;
|
||||
using iterator = SwapBackVectorIterator<SwapBackVector<T, capacity_in>>;
|
||||
using const_iterator = SwapBackVectorConstIterator<SwapBackVector<T, capacity_in>>;
|
||||
|
||||
public:
|
||||
SwapBackVector()
|
||||
{
|
||||
m_data = new T[capacity_in];
|
||||
}
|
||||
|
||||
~SwapBackVector()
|
||||
{
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
SwapBackVector(const SwapBackVector<T>& other)
|
||||
{
|
||||
m_nextValidIndex = other.m_nextValidIndex;
|
||||
for (int i = 0; i < m_nextValidIndex; i++)
|
||||
{
|
||||
m_data[i] = other.m_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
SwapBackVector(SwapBackVector<T>&& other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
other.m_data = nullptr;
|
||||
m_nextValidIndex = other.m_nextValidIndex;
|
||||
}
|
||||
|
||||
SwapBackVector<T>& operator=(const SwapBackVector<T>& rhs)
|
||||
{
|
||||
if (this == &rhs) return this;
|
||||
|
||||
m_nextValidIndex = rhs.m_nextValidIndex;
|
||||
for (int i = 0; i < m_nextValidIndex; i++)
|
||||
{
|
||||
m_data[i] = rhs.m_data[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SwapBackVector<T>& operator=(SwapBackVector<T>&& rhs)
|
||||
{
|
||||
if (this == &rhs) return this;
|
||||
|
||||
delete[] m_data;
|
||||
m_data = rhs.m_data;
|
||||
rhs.m_data = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
T& operator[](EntityIndex index)
|
||||
{
|
||||
assert(index < m_nextValidIndex && "ASSERT ERROR -> SwapBackVector.hpp: attempting to index beyond next valid index");
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
const T& operator[](EntityIndex index) const
|
||||
{
|
||||
assert(index < m_nextValidIndex && "ASSERT ERROR -> SwapBackVector.hpp: attempting to index beyond next valid index");
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
public:
|
||||
T* data() { return m_data; }
|
||||
|
||||
const T* data() const { return m_data; }
|
||||
|
||||
void remove(EntityIndex index)
|
||||
{
|
||||
if (index >= m_nextValidIndex) return;
|
||||
|
||||
m_data[index] = m_data[m_nextValidIndex - 1];
|
||||
m_nextValidIndex--;
|
||||
}
|
||||
|
||||
void push()
|
||||
{
|
||||
assert(capacity_in > m_nextValidIndex);
|
||||
|
||||
m_data[m_nextValidIndex] = T();
|
||||
m_nextValidIndex++;
|
||||
}
|
||||
|
||||
void push(const T& data)
|
||||
{
|
||||
assert(capacity_in > m_nextValidIndex);
|
||||
|
||||
m_data[m_nextValidIndex] = data;
|
||||
m_nextValidIndex++;
|
||||
}
|
||||
inline EntityIndex size() const { return m_nextValidIndex; }
|
||||
|
||||
inline constexpr EntityIndex capacity() const { return capacity_in; }
|
||||
|
||||
iterator begin() { return iterator(m_data); }
|
||||
|
||||
iterator end() { return iterator(m_data + m_nextValidIndex); }
|
||||
|
||||
const_iterator cbegin() const { return const_iterator(m_data); }
|
||||
|
||||
const_iterator cend() const { return const_iterator(m_data + m_nextValidIndex); }
|
||||
|
||||
private:
|
||||
T* m_data;
|
||||
EntityIndex m_nextValidIndex{};
|
||||
};
|
||||
|
||||
|
||||
//bool specialization
|
||||
template<EntityIndex capacity_in>
|
||||
class SwapBackVector<bool, capacity_in>
|
||||
{
|
||||
public:
|
||||
SwapBackVector()
|
||||
{
|
||||
m_data = new uint8_t[(capacity_in / 8) + 1];
|
||||
}
|
||||
|
||||
~SwapBackVector()
|
||||
{
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
SwapBackVector(const SwapBackVector& other) = delete;
|
||||
SwapBackVector(SwapBackVector&& other) = delete;
|
||||
|
||||
SwapBackVector& operator=(const SwapBackVector& rhs) = delete;
|
||||
SwapBackVector& operator=(SwapBackVector&& rhs) = delete;
|
||||
|
||||
public:
|
||||
bool operator[](EntityIndex index)
|
||||
{
|
||||
//assert(index < m_nextValidIndex && "ASSERT ERROR -> SwapBackVector.hpp: attempting to index beyond next valid index");
|
||||
EntityIndex clusterIndex = index / 8u;
|
||||
EntityIndex stateIndex = index % 8u;
|
||||
return m_data[clusterIndex] & (1 << stateIndex);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&, const SwapBackVector<bool>&);
|
||||
public:
|
||||
void remove(EntityIndex index)
|
||||
{
|
||||
if (index >= m_nextValidIndex) return;
|
||||
|
||||
readAt(m_nextValidIndex - 1) ? setTrueAt(index) : setFalseAt(index);
|
||||
m_nextValidIndex--;
|
||||
}
|
||||
|
||||
void push()
|
||||
{
|
||||
assert(capacity_in > m_nextValidIndex);
|
||||
|
||||
setFalseAt(m_nextValidIndex);
|
||||
m_nextValidIndex++;
|
||||
}
|
||||
|
||||
void push(bool state)
|
||||
{
|
||||
assert(capacity_in > m_nextValidIndex);
|
||||
|
||||
state ? setTrueAt(m_nextValidIndex) : setFalseAt(m_nextValidIndex);
|
||||
m_nextValidIndex++;
|
||||
}
|
||||
|
||||
bool readAt(EntityIndex index) const
|
||||
{
|
||||
EntityIndex clusterIndex = index / 8u;
|
||||
EntityIndex stateIndex = index % 8u;
|
||||
return m_data[clusterIndex] & 1 << stateIndex;
|
||||
}
|
||||
|
||||
void setTrueAt(EntityIndex index)
|
||||
{
|
||||
EntityIndex clusterIndex = index / 8u;
|
||||
EntityIndex stateIndex = index % 8u;
|
||||
m_data[clusterIndex] |= 1 << stateIndex;
|
||||
}
|
||||
|
||||
void setFalseAt(EntityIndex index)
|
||||
{
|
||||
EntityIndex clusterIndex = index / 8u;
|
||||
EntityIndex stateIndex = index % 8u;
|
||||
m_data[clusterIndex] &= ~(1 << stateIndex);
|
||||
}
|
||||
|
||||
inline EntityIndex size() const { return m_nextValidIndex; }
|
||||
|
||||
inline constexpr EntityIndex capacity() const { return capacity_in; }
|
||||
|
||||
private:
|
||||
uint8_t* m_data;
|
||||
EntityIndex m_nextValidIndex{};
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const SwapBackVector<bool>& vec)
|
||||
{
|
||||
for(size_t i = 0; i < (vec.size() / 8) + 1; i++)
|
||||
{
|
||||
out << std::bitset<8>(vec.m_data[i]) << " ";
|
||||
}
|
||||
out << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
//Entity specialization
|
||||
template<EntityIndex capacity_in>
|
||||
class SwapBackVector<Entity, capacity_in>
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
//#include "SwapBackVector.hpp"
|
||||
#include <Entities/Entity.h>
|
||||
#include <cassert>
|
||||
//#include <cstdint>
|
||||
//#include <cstddef>
|
||||
//#include <iterator>
|
||||
|
||||
template<typename SwapBackVector>
|
||||
class SwapBackVectorIterator
|
||||
{
|
||||
public:
|
||||
using data_type = typename SwapBackVector::data_type;
|
||||
using pointer = data_type*;
|
||||
using reference = data_type&;
|
||||
|
||||
public:
|
||||
SwapBackVectorIterator(pointer ptr)
|
||||
: m_ptr(ptr)
|
||||
{}
|
||||
|
||||
SwapBackVectorIterator& operator++()
|
||||
{
|
||||
m_ptr++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SwapBackVectorIterator operator++(int)
|
||||
{
|
||||
SwapBackVectorIterator it = *this;
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
SwapBackVectorIterator& operator--()
|
||||
{
|
||||
m_ptr--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SwapBackVectorIterator operator--(int)
|
||||
{
|
||||
SwapBackVectorIterator it = *this;
|
||||
--(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
reference operator[](int index) { return m_ptr[index]; }
|
||||
|
||||
pointer operator->() { return m_ptr; }
|
||||
|
||||
reference operator*() { return *m_ptr; }
|
||||
|
||||
bool operator==(const SwapBackVectorIterator& rhs) { return m_ptr == rhs.m_ptr; }
|
||||
bool operator!=(const SwapBackVectorIterator& rhs) { return !(m_ptr == rhs.m_ptr); }
|
||||
private:
|
||||
data_type* m_ptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename SwapBackVector>
|
||||
class SwapBackVectorConstIterator
|
||||
{
|
||||
public:
|
||||
using data_type = typename SwapBackVector::data_type;
|
||||
using pointer = const data_type*;
|
||||
using reference = const data_type&;
|
||||
|
||||
public:
|
||||
SwapBackVectorConstIterator(pointer ptr)
|
||||
: m_ptr(ptr)
|
||||
{}
|
||||
|
||||
SwapBackVectorConstIterator& operator++()
|
||||
{
|
||||
m_ptr++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SwapBackVectorConstIterator operator++(int)
|
||||
{
|
||||
SwapBackVectorConstIterator it = *this;
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
SwapBackVectorConstIterator& operator--()
|
||||
{
|
||||
m_ptr--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SwapBackVectorConstIterator operator--(int)
|
||||
{
|
||||
SwapBackVectorConstIterator it = *this;
|
||||
--(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
reference operator[](int index) { return m_ptr[index]; }
|
||||
|
||||
pointer operator->() { return m_ptr; }
|
||||
|
||||
reference operator*() { return *m_ptr; }
|
||||
|
||||
bool operator==(const SwapBackVectorConstIterator& rhs) { return m_ptr == rhs.m_ptr; }
|
||||
bool operator!=(const SwapBackVectorConstIterator& rhs) { return !(m_ptr == rhs.m_ptr); }
|
||||
private:
|
||||
data_type* m_ptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef LOG_ENABLE
|
||||
#define LOG(x) std::cout << x << "\n"
|
||||
#else
|
||||
#define LOG(x)
|
||||
#endif
|
||||
|
|
@ -1,24 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include<Entities.h>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
using u8 = uint8_t;
|
||||
using u16 = uint16_t;
|
||||
using u32 = uint32_t;
|
||||
using u64 = uint64_t;
|
||||
using s8 = int8_t;
|
||||
using s16 = int16_t;
|
||||
using s32 = int32_t;
|
||||
using s64 = int64_t;
|
||||
|
||||
using EntityIndex = u16;
|
||||
|
||||
enum EntityTag : u8
|
||||
{
|
||||
player,
|
||||
tile,
|
||||
enemy,
|
||||
tagCount
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace util
|
||||
{
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
|
||||
inline constexpr EntityIndex MAX_ENTITIES {60'000u};
|
||||
inline constexpr EntityIndex MAX_TILES {1'000u};
|
||||
inline constexpr EntityIndex MAX_ENEMIES {1'000u};
|
||||
|
||||
// used for imgui
|
||||
inline constexpr std::array<const char*, 1> tagStringsC =
|
||||
inline constexpr std::array<const char*, tagCount> tagStringsC =
|
||||
{
|
||||
"none"
|
||||
"player"
|
||||
};
|
||||
|
||||
inline constexpr std::array<std::string_view, 1> tagStrings =
|
||||
inline constexpr std::array<std::string_view, tagCount> tagStrings =
|
||||
{
|
||||
"none"sv
|
||||
"player"sv
|
||||
};
|
||||
|
||||
inline constexpr std::array<EntityIndex, tagCount> tagStart =
|
||||
{
|
||||
0,//player
|
||||
1,//tile start
|
||||
MAX_TILES,//enemy start
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
38
premake5.lua
38
premake5.lua
|
|
@ -1,4 +1,5 @@
|
|||
require "ecc/ecc"
|
||||
require "ninja/ninja"
|
||||
|
||||
workspace "fake-mario"
|
||||
architecture "x64"
|
||||
|
|
@ -27,8 +28,9 @@ local vs_includedir = "$(SolutionDir)include"
|
|||
local includedir = "%{wks.location}/include"
|
||||
|
||||
project "fake-mario"
|
||||
cppdialect "C++17"
|
||||
language "C++"
|
||||
cppdialect "C++17"
|
||||
systemversion "latest"
|
||||
|
||||
files
|
||||
{
|
||||
|
|
@ -42,11 +44,11 @@ project "fake-mario"
|
|||
"vendor/imgui/imgui-SFML.cpp"
|
||||
}
|
||||
|
||||
|
||||
--visual studio--
|
||||
filter {"action:vs*", "system:windows"}
|
||||
targetdir (vs_bindir)
|
||||
objdir (vs_intdir)
|
||||
staticruntime "on"
|
||||
includedirs
|
||||
{
|
||||
vs_includedir,
|
||||
|
|
@ -60,6 +62,7 @@ project "fake-mario"
|
|||
filter {"action:vs*", "system:windows", "configurations:release"}
|
||||
libdirs {vs_libreldir}
|
||||
|
||||
|
||||
--not visual studio on windows--
|
||||
filter {"not action:vs*", "system:windows"}
|
||||
targetdir (bindir)
|
||||
|
|
@ -77,17 +80,14 @@ project "fake-mario"
|
|||
libdirs {libreldir}
|
||||
|
||||
|
||||
|
||||
--platform specific settings--
|
||||
--windows specific settings--
|
||||
filter{"system:windows"}
|
||||
systemversion "latest"
|
||||
defines "SFML_STATIC"
|
||||
defines "PLATFORM_WINDOWS"
|
||||
staticruntime "on"
|
||||
|
||||
filter {"system:windows", "configurations:debug"}
|
||||
kind "ConsoleApp"
|
||||
defines{"_DEBUG", "_CONSOLE"}
|
||||
runtime "Debug"
|
||||
links
|
||||
{
|
||||
"sfml-graphics-s-d",
|
||||
|
|
@ -108,12 +108,7 @@ project "fake-mario"
|
|||
}
|
||||
|
||||
filter {"system:windows", "configurations:release"}
|
||||
kind "WindowedApp"
|
||||
optimize "Speed"
|
||||
inlining "Auto"
|
||||
entrypoint "mainCRTStartup"
|
||||
defines{"NDEBUG"}
|
||||
runtime "Release"
|
||||
links
|
||||
{
|
||||
"sfml-graphics-s",
|
||||
|
|
@ -133,17 +128,17 @@ project "fake-mario"
|
|||
"winmm"
|
||||
}
|
||||
|
||||
|
||||
--linux specific settings
|
||||
filter {"system:linux"}
|
||||
targetdir (bindir)
|
||||
objdir (intdir)
|
||||
defines "PLATFORM_LINUX"
|
||||
includedirs
|
||||
{
|
||||
includedir,
|
||||
sfmldir .. "/include",
|
||||
imguidir
|
||||
}
|
||||
systemversion "latest"
|
||||
defines "PLATFORM_LINUX"
|
||||
links
|
||||
{
|
||||
"sfml-graphics",
|
||||
|
|
@ -154,15 +149,18 @@ project "fake-mario"
|
|||
"OpenGL",
|
||||
}
|
||||
|
||||
filter {"system:linux" , "configurations:debug"}
|
||||
kind "ConsoleApp"
|
||||
|
||||
--config settings
|
||||
filter "configurations:debug"
|
||||
defines"LOG_ENABLE"
|
||||
symbols "on"
|
||||
runtime "Debug"
|
||||
kind "ConsoleApp"
|
||||
|
||||
filter {"system:linux" , "configurations:release"}
|
||||
kind "WindowedApp"
|
||||
filter "configurations:release"
|
||||
optimize "Speed"
|
||||
inlining "Auto"
|
||||
entrypoint "mainCRTStartup"
|
||||
symbols "off"
|
||||
runtime "Release"
|
||||
kind "WindowedApp"
|
||||
entrypoint "mainCRTStartup"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@
|
|||
#include <Entities/EntityMemoryPool.h>
|
||||
|
||||
#include <utility.h>
|
||||
//#include <utility>
|
||||
|
||||
Entity::Entity(EntityIndex id_in)
|
||||
: m_id(id_in)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Entity::hasComponent() const
|
||||
|
|
@ -31,6 +36,11 @@ void Entity::addComponent(const T&& data)
|
|||
component.active = true;
|
||||
}
|
||||
|
||||
EntityIndex Entity::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
EntityTag Entity::tag() const
|
||||
{
|
||||
return EntityMemoryPool::instance().getTag(m_id);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,16 @@
|
|||
#include "Entities/EntityView.h"
|
||||
#include "utility.h"
|
||||
#include <Entities/EntityManager.h>
|
||||
#include <Entities/Entity.h>
|
||||
|
||||
inline constexpr EntityIndex PLAYER_INDEX = 0;
|
||||
|
||||
inline Entity EntityManager::player()
|
||||
{
|
||||
return m_player;
|
||||
}
|
||||
|
||||
EntityView EntityManager::getEntiites(EntityTag tag)
|
||||
{
|
||||
return EntityView(util::tagStart[tag], m_numEntitiesByTag[tag]);
|
||||
}
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
#include <Entities/EntityMemoryPool.h>
|
||||
|
||||
#include <Entities/Entity.h>
|
||||
#include <Globals.h>
|
||||
//#include <cstddef>
|
||||
#include <vector>
|
||||
#include <utility.h>
|
||||
|
||||
EntityMemoryPool::EntityMemoryPool()
|
||||
{
|
||||
std::apply([=](auto&&... args) {((args.reserve(Global::MAX_ENTITIES)), ...); }, m_components);
|
||||
m_tags.reserve(Global::MAX_ENTITIES);
|
||||
m_aliveStates.reserve(Global::MAX_ENTITIES);
|
||||
|
||||
std::apply([=](auto&&... args) {((args.reserve(util::MAX_ENTITIES)), ...); }, m_components);
|
||||
m_tags.reserve(util::MAX_ENTITIES);
|
||||
m_aliveStates.reserve(util::MAX_ENTITIES);
|
||||
}
|
||||
|
||||
EntityMemoryPool& EntityMemoryPool::instance()
|
||||
|
|
@ -46,3 +44,9 @@ bool EntityMemoryPool::getAlive(EntityIndex id) const
|
|||
{
|
||||
return m_aliveStates[id];
|
||||
}
|
||||
|
||||
void EntityMemoryPool::removeEntity(EntityIndex id)
|
||||
{
|
||||
m_aliveStates[id] = false;
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
#include <Entities/EntityView.h>
|
||||
#include "utility.h"
|
||||
|
||||
EntityView::EntityView(EntityIndex start, EntityIndex size)
|
||||
: m_start(start)
|
||||
, m_size(size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//non-const iterator
|
||||
EntityViewIterator::EntityViewIterator(EntityIndex index)
|
||||
: m_currentEntity(index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EntityViewIterator& EntityViewIterator::operator++()
|
||||
{
|
||||
m_currentEntity.m_id++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EntityViewIterator EntityViewIterator::operator++(int)
|
||||
{
|
||||
m_currentEntity.m_id++;
|
||||
return m_currentEntity.m_id - 1;
|
||||
}
|
||||
|
||||
EntityViewIterator& EntityViewIterator::operator--()
|
||||
{
|
||||
m_currentEntity.m_id--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EntityViewIterator EntityViewIterator::operator--(int)
|
||||
{
|
||||
m_currentEntity.m_id--;
|
||||
return m_currentEntity.m_id + 1;
|
||||
}
|
||||
|
||||
Entity EntityViewIterator::operator*()
|
||||
{
|
||||
return m_currentEntity;
|
||||
}
|
||||
|
||||
Entity EntityViewIterator::operator[](int index)
|
||||
{
|
||||
return m_currentEntity.m_id + index;
|
||||
}
|
||||
|
||||
Entity* EntityViewIterator::operator->()
|
||||
{
|
||||
return &m_currentEntity;
|
||||
}
|
||||
|
||||
bool EntityViewIterator::operator==(EntityViewIterator other)
|
||||
{
|
||||
return m_currentEntity.m_id == other->m_id;
|
||||
}
|
||||
|
||||
bool EntityViewIterator::operator!=(EntityViewIterator other)
|
||||
{
|
||||
return m_currentEntity.m_id != other->m_id;
|
||||
}
|
||||
|
||||
//const iterator
|
||||
EntityViewConstIterator::EntityViewConstIterator(EntityIndex index)
|
||||
: m_currentEntity(index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EntityViewConstIterator& EntityViewConstIterator::operator++()
|
||||
{
|
||||
m_currentEntity.m_id++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EntityViewConstIterator EntityViewConstIterator::operator++(int)
|
||||
{
|
||||
m_currentEntity.m_id++;
|
||||
return m_currentEntity.m_id - 1;
|
||||
}
|
||||
|
||||
EntityViewConstIterator& EntityViewConstIterator::operator--()
|
||||
{
|
||||
m_currentEntity.m_id--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EntityViewConstIterator EntityViewConstIterator::operator--(int)
|
||||
{
|
||||
m_currentEntity.m_id--;
|
||||
return m_currentEntity.m_id + 1;
|
||||
}
|
||||
|
||||
const Entity EntityViewConstIterator::operator*()
|
||||
{
|
||||
return m_currentEntity;
|
||||
}
|
||||
|
||||
const Entity EntityViewConstIterator::operator[](int index)
|
||||
{
|
||||
return m_currentEntity.m_id + index;
|
||||
}
|
||||
|
||||
const Entity* EntityViewConstIterator::operator->()
|
||||
{
|
||||
return &m_currentEntity;
|
||||
}
|
||||
|
||||
bool EntityViewConstIterator::operator==(EntityViewConstIterator other)
|
||||
{
|
||||
return m_currentEntity.m_id == other->m_id;
|
||||
}
|
||||
|
||||
bool EntityViewConstIterator::operator!=(EntityViewConstIterator other)
|
||||
{
|
||||
return m_currentEntity.m_id != other->m_id;
|
||||
}
|
||||
18
src/main.cpp
18
src/main.cpp
|
|
@ -1,29 +1,15 @@
|
|||
#include "Globals.h"
|
||||
#include "SwapBackVector.hpp"
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <imgui-SFML.h>
|
||||
#include <imgui.h>
|
||||
|
||||
//#include <iostream>
|
||||
#include <Entities.h>
|
||||
#include <iostream>
|
||||
#include <utility.h>
|
||||
#include <vector>
|
||||
|
||||
int main()
|
||||
{
|
||||
SwapBackVector<bool> arr;
|
||||
|
||||
arr.push(true);
|
||||
arr.push(true);
|
||||
arr.push();
|
||||
|
||||
arr.setTrueAt(0);
|
||||
|
||||
std::cout << arr;
|
||||
// for (auto x : arr)
|
||||
// {
|
||||
// std::cout << x << "\n";
|
||||
// }
|
||||
|
||||
auto window = sf::RenderWindow(sf::VideoMode({ 1920u, 1080u }), "Fake Mario");
|
||||
window.setFramerateLimit(144);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# Keep GitHub Actions up to date with GitHub's Dependabot... dependabot.yml
|
||||
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
|
||||
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*" # Group all Actions updates into a single larger pull request
|
||||
schedule:
|
||||
interval: weekly
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
name: macos
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/macos.yml'
|
||||
- 'tests/**'
|
||||
- '**/*.lua'
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/macos.yml'
|
||||
- 'tests/**'
|
||||
- '**/*.lua'
|
||||
|
||||
jobs:
|
||||
macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: mymindstorm/setup-emsdk@v14
|
||||
|
||||
- name: install premake5
|
||||
uses: Jarod42/install-premake5@v6
|
||||
|
||||
- name: install ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v6
|
||||
|
||||
- name: Versions
|
||||
run: |
|
||||
python --version
|
||||
premake5 --version
|
||||
ninja --version
|
||||
|
||||
- name: test projects
|
||||
run: cd tests && python run_tests.py
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
name: ubuntu
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/ubuntu.yml'
|
||||
- 'tests/**'
|
||||
- '**/*.lua'
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/ubuntu.yml'
|
||||
- 'tests/**'
|
||||
- '**/*.lua'
|
||||
|
||||
jobs:
|
||||
ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: mymindstorm/setup-emsdk@v14
|
||||
|
||||
- name: install premake5
|
||||
uses: Jarod42/install-premake5@v6
|
||||
|
||||
- name: apt-get update
|
||||
run: sudo apt-get update -y
|
||||
|
||||
- name: apt-get install ninja-build
|
||||
run: |
|
||||
sudo apt-get install -y ninja-build
|
||||
|
||||
- name: Versions
|
||||
run: |
|
||||
python --version
|
||||
premake5 --version
|
||||
ninja --version
|
||||
|
||||
- name: test projects
|
||||
run: cd tests && python run_tests.py
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
name: windows
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/windows.yml'
|
||||
- 'tests/**'
|
||||
- '**/*.lua'
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/windows.yml'
|
||||
- 'tests/**'
|
||||
- '**/*.lua'
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: mymindstorm/setup-emsdk@v14
|
||||
|
||||
- name: install premake5
|
||||
uses: Jarod42/install-premake5@v6
|
||||
|
||||
- name: install ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v6
|
||||
|
||||
- name: Versions
|
||||
run: |
|
||||
python --version
|
||||
premake5 --version
|
||||
ninja --version
|
||||
|
||||
- name: Add cl.exe to PATH
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: test projects
|
||||
run: cd tests && python run_tests.py
|
||||
shell: bash
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Dmitry Ivanov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# premake-ninja
|
||||
|
||||
[Premake](https://github.com/premake/premake-core) module to support [Ninja](https://github.com/martine/ninja), because it's awesome.
|
||||
|
||||
## Usage (little reminder)
|
||||
1. Put these files in a "premake-ninja" subdirectory of [Premake search paths](https://premake.github.io/docs/Locating-Scripts/).<br>
|
||||
|
||||
2. Adapt your premake5.lua script, or better: create/adapt your [premake-system.lua](https://premake.github.io/docs/System-Scripts/)
|
||||
|
||||
```lua
|
||||
require "premake-ninja/ninja"
|
||||
```
|
||||
|
||||
3. Generate ninja files
|
||||
|
||||
```sh
|
||||
premake5 ninja
|
||||
```
|
||||
On msys2 (mingw)
|
||||
```sh
|
||||
premake5 ninja --cc=gcc --shell=posix
|
||||
```
|
||||
|
||||
4. Run ninja
|
||||
|
||||
For each project - configuration pair, we create separate .ninja file. For solution we create build.ninja file which imports other .ninja files with subninja command.
|
||||
|
||||
Build.ninja file sets phony targets for configuration names so you can build them from command line. And default target is the first configuration name in your project (usually default).
|
||||
|
||||
General from:
|
||||
```sh
|
||||
ninja $(YourProjectName)_$(ConfigName)
|
||||
```
|
||||
as example:
|
||||
```sh
|
||||
ninja myapp_Release
|
||||
```
|
||||
|
||||
### Tested on   
|
||||
|
||||
### Extra Tests
|
||||
|
||||
Part of integration tests of several generators in https://github.com/Jarod42/premake-sample-projects 
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
return {
|
||||
"_preload.lua",
|
||||
"ninja.lua",
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
--
|
||||
-- Name: premake-ninja/_preload.lua
|
||||
-- Purpose: Define the ninja action.
|
||||
-- Author: Dmitry Ivanov
|
||||
-- Created: 2015/07/04
|
||||
-- Copyright: (c) 2015 Dmitry Ivanov
|
||||
--
|
||||
|
||||
local p = premake
|
||||
|
||||
newaction
|
||||
{
|
||||
-- Metadata for the command line and help system
|
||||
trigger = "ninja",
|
||||
shortname = "ninja",
|
||||
description = "Ninja is a small build system with a focus on speed",
|
||||
|
||||
-- The capabilities of this action
|
||||
valid_kinds = {"ConsoleApp", "WindowedApp", "SharedLib", "StaticLib", "None"}, -- Not supported: Makefile, Packaging, SharedItems, Utility
|
||||
valid_languages = {"C", "C++"},
|
||||
valid_tools = {cc = { "gcc", "clang", "msc", "emcc" }},
|
||||
|
||||
toolset = iif(os.target() == "windows", "msc-v142", -- Visual Studio 2019
|
||||
iif(os.target() == "macosx", "clang", "gcc")),
|
||||
|
||||
-- Workspace and project generation logic
|
||||
onWorkspace = function(wks)
|
||||
p.eol("\r\n")
|
||||
p.indent(" ")
|
||||
p.generate(wks, "build.ninja", p.modules.ninja.generateWorkspace)
|
||||
end,
|
||||
onProject = function(prj)
|
||||
p.eol("\r\n")
|
||||
p.indent(" ")
|
||||
p.modules.ninja.generateProject(prj)
|
||||
end,
|
||||
onBranch = function(prj)
|
||||
p.eol("\r\n")
|
||||
p.indent(" ")
|
||||
p.modules.ninja.generateProject(prj)
|
||||
end,
|
||||
onCleanSolution = function(sln)
|
||||
-- TODO
|
||||
end,
|
||||
onCleanProject = function(prj)
|
||||
-- TODO
|
||||
end,
|
||||
onCleanTarget = function(prj)
|
||||
-- TODO
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
-- Decide when the full module should be loaded.
|
||||
--
|
||||
|
||||
return function(cfg)
|
||||
return (_ACTION == "ninja")
|
||||
end
|
||||
|
|
@ -0,0 +1,845 @@
|
|||
--
|
||||
-- Name: premake-ninja/ninja.lua
|
||||
-- Purpose: Define the ninja action.
|
||||
-- Author: Dmitry Ivanov
|
||||
-- Created: 2015/07/04
|
||||
-- Copyright: (c) 2015 Dmitry Ivanov
|
||||
--
|
||||
|
||||
local p = premake
|
||||
local tree = p.tree
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
local fileconfig = p.fileconfig
|
||||
|
||||
-- Some toolset fixes/helper
|
||||
p.tools.clang.objectextension = ".o"
|
||||
p.tools.gcc.objectextension = ".o"
|
||||
p.tools.msc.objectextension = ".obj"
|
||||
|
||||
p.tools.clang.tools.rc = p.tools.clang.tools.rc or "windres"
|
||||
|
||||
p.tools.msc.gettoolname = function(cfg, name)
|
||||
local map = {cc = "cl", cxx = "cl", ar = "lib", rc = "rc"}
|
||||
return map[name]
|
||||
end
|
||||
|
||||
-- Ninja module
|
||||
premake.modules.ninja = {}
|
||||
local ninja = p.modules.ninja
|
||||
|
||||
ninja.handlers = {}
|
||||
|
||||
function ninja.register_handler(kind, compilation_rules, target_rules)
|
||||
ninja.handlers[kind] = { compilation_rules = compilation_rules, target_rules = target_rules }
|
||||
end
|
||||
|
||||
local function get_key(cfg, name)
|
||||
local name = name or cfg.project.name
|
||||
|
||||
if cfg.platform then
|
||||
return name .. "_" .. cfg.buildcfg .. "_" .. cfg.platform
|
||||
else
|
||||
return name .. "_" .. cfg.buildcfg
|
||||
end
|
||||
end
|
||||
|
||||
local build_cache = {}
|
||||
|
||||
function ninja.add_build(cfg, out, implicit_outputs, command, inputs, implicit_inputs, dependencies, vars)
|
||||
implicit_outputs = ninja.list(table.translate(implicit_outputs, ninja.esc))
|
||||
if #implicit_outputs > 0 then
|
||||
implicit_outputs = " |" .. implicit_outputs
|
||||
else
|
||||
implicit_outputs = ""
|
||||
end
|
||||
|
||||
inputs = ninja.list(table.translate(inputs, ninja.esc))
|
||||
|
||||
implicit_inputs = ninja.list(table.translate(implicit_inputs, ninja.esc))
|
||||
if #implicit_inputs > 0 then
|
||||
implicit_inputs = " |" .. implicit_inputs
|
||||
else
|
||||
implicit_inputs = ""
|
||||
end
|
||||
|
||||
dependencies = ninja.list(table.translate(dependencies, ninja.esc))
|
||||
if #dependencies > 0 then
|
||||
dependencies = " ||" .. dependencies
|
||||
else
|
||||
dependencies = ""
|
||||
end
|
||||
build_line = "build " .. ninja.esc(out) .. implicit_outputs .. ": " .. command .. inputs .. implicit_inputs .. dependencies
|
||||
|
||||
local cached = build_cache[out]
|
||||
if cached ~= nil then
|
||||
if build_line == cached.build_line
|
||||
and table.equals(vars or {}, cached.vars or {})
|
||||
then
|
||||
-- custom_command/copy rule are identical for each configuration (contrary to other rules)
|
||||
-- So we can compare extra parameter
|
||||
if command == "custom_command" or command == "copy" then
|
||||
p.outln("# INFO: Rule ignored, same as " .. cached.cfg_key)
|
||||
else
|
||||
local cfg_key = get_key(cfg)
|
||||
p.warn(cached.cfg_key .. " and " .. cfg_key .. " both generate (differently?) " .. out .. ". Ignoring " .. cfg_key)
|
||||
p.outln("# WARNING: Rule ignored, using the one from " .. cached.cfg_key)
|
||||
end
|
||||
else
|
||||
local cfg_key = get_key(cfg)
|
||||
p.warn(cached.cfg_key .. " and " .. cfg_key .. " both generate differently " .. out .. ". Ignoring " .. cfg_key)
|
||||
p.outln("# ERROR: Rule ignored, using the one from " .. cached.cfg_key)
|
||||
end
|
||||
p.outln("# " .. build_line)
|
||||
for i, var in ipairs(vars or {}) do
|
||||
p.outln("# " .. var)
|
||||
end
|
||||
return
|
||||
end
|
||||
p.outln(build_line)
|
||||
for i, var in ipairs(vars or {}) do
|
||||
p.outln(" " .. var)
|
||||
end
|
||||
build_cache[out] = {
|
||||
cfg_key = get_key(cfg),
|
||||
build_line = build_line,
|
||||
vars = vars
|
||||
}
|
||||
end
|
||||
|
||||
function ninja.esc(value)
|
||||
value = value:gsub("%$", "$$") -- TODO maybe there is better way
|
||||
value = value:gsub(":", "$:")
|
||||
value = value:gsub("\n", "$\n")
|
||||
value = value:gsub(" ", "$ ")
|
||||
return value
|
||||
end
|
||||
|
||||
function ninja.quote(value)
|
||||
value = value:gsub("\\", "\\\\")
|
||||
value = value:gsub("'", "\\'")
|
||||
value = value:gsub("\"", "\\\"")
|
||||
|
||||
return "\"" .. value .. "\""
|
||||
end
|
||||
|
||||
-- in some cases we write file names in rule commands directly
|
||||
-- so we need to propely escape them
|
||||
function ninja.shesc(value)
|
||||
if type(value) == "table" then
|
||||
local result = {}
|
||||
local n = #value
|
||||
for i = 1, n do
|
||||
table.insert(result, ninja.shesc(value[i]))
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
if value:find(' ') or value:find('"') or value:find('(', 1, true) or value:find(')') or value:find('|') or value:find('&') then
|
||||
return ninja.quote(value)
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function ninja.can_generate(prj)
|
||||
return p.action.supports(prj.kind) and prj.kind ~= p.NONE
|
||||
end
|
||||
|
||||
-- generate solution that will call ninja for projects
|
||||
function ninja.generateWorkspace(wks)
|
||||
local oldGetDefaultSeparator = path.getDefaultSeparator
|
||||
path.getDefaultSeparator = function() return "/" end
|
||||
|
||||
p.outln("# solution build file")
|
||||
p.outln("# generated with premake ninja")
|
||||
p.outln("")
|
||||
|
||||
p.outln("# build projects")
|
||||
local cfgs = {} -- key is concatenated name or variant name, value is string of outputs names
|
||||
local key = ""
|
||||
local cfg_first = nil
|
||||
local cfg_first_lib = nil
|
||||
local subninjas = {}
|
||||
|
||||
for prj in p.workspace.eachproject(wks) do
|
||||
if ninja.can_generate(prj) then
|
||||
for cfg in p.project.eachconfig(prj) do
|
||||
key = get_key(cfg)
|
||||
|
||||
if not cfgs[cfg.buildcfg] then cfgs[cfg.buildcfg] = {} end
|
||||
table.insert(cfgs[cfg.buildcfg], key)
|
||||
|
||||
-- set first configuration name
|
||||
if wks.defaultplatform == nil then
|
||||
if (cfg_first == nil) and (cfg.kind == p.CONSOLEAPP or cfg.kind == p.WINDOWEDAPP) then
|
||||
cfg_first = key
|
||||
end
|
||||
end
|
||||
if (cfg_first_lib == nil) and (cfg.kind == p.STATICLIB or cfg.kind == p.SHAREDLIB) then
|
||||
cfg_first_lib = key
|
||||
end
|
||||
if prj.name == wks.startproject then
|
||||
if wks.defaultplatform == nil then
|
||||
cfg_first = key
|
||||
elseif cfg.platform == wks.defaultplatform then
|
||||
if cfg_first == nil then
|
||||
cfg_first = key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- include other ninja file
|
||||
table.insert(subninjas, ninja.esc(ninja.projectCfgFilename(cfg, true)))
|
||||
p.outln("subninja " .. ninja.esc(ninja.projectCfgFilename(cfg, true)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if cfg_first == nil then cfg_first = cfg_first_lib end
|
||||
|
||||
p.outln("")
|
||||
|
||||
p.outln("# targets")
|
||||
for cfg, outputs in spairs(cfgs) do
|
||||
p.outln("build " .. ninja.esc(cfg) .. ": phony" .. ninja.list(table.translate(outputs, ninja.esc)))
|
||||
end
|
||||
p.outln("")
|
||||
|
||||
if wks.editorintegration then
|
||||
-- we need to filter out the 'file' argument, since we already output
|
||||
-- the script separately.
|
||||
local args = {}
|
||||
for _, arg in ipairs(_ARGV) do
|
||||
if not (arg:startswith("--file") or arg:startswith("/file")) then
|
||||
table.insert(args, arg);
|
||||
end
|
||||
end
|
||||
table.sort(args)
|
||||
|
||||
p.outln('# Rule')
|
||||
p.outln('rule premake')
|
||||
p.outln(' command = ' .. ninja.shesc(p.workspace.getrelative(wks, _PREMAKE_COMMAND)) .. ' --file=$in ' .. table.concat(ninja.shesc(args), ' '))
|
||||
p.outln(' generator = true')
|
||||
p.outln(' restat = true')
|
||||
p.outln("")
|
||||
p.outln('build build.ninja ' .. table.concat(subninjas, " ") .. ': premake ' .. p.workspace.getrelative(wks, _MAIN_SCRIPT))
|
||||
p.outln("")
|
||||
end
|
||||
|
||||
if cfg_first then
|
||||
p.outln("# default target")
|
||||
p.outln("default " .. ninja.esc(cfg_first))
|
||||
p.outln("")
|
||||
end
|
||||
|
||||
path.getDefaultSeparator = oldGetDefaultSeparator
|
||||
end
|
||||
|
||||
function ninja.list(value)
|
||||
if #value > 0 then
|
||||
return " " .. table.concat(value, " ")
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
local function shouldcompileasc(filecfg)
|
||||
if filecfg.compileas and filecfg.compileas ~= "Default" then
|
||||
return p.languages.isc(filecfg.compileas)
|
||||
end
|
||||
return path.iscfile(filecfg.abspath)
|
||||
end
|
||||
|
||||
local function shouldcompileascpp(filecfg)
|
||||
if filecfg.compileas and filecfg.compileas ~= "Default" then
|
||||
return p.languages.iscpp(filecfg.compileas)
|
||||
end
|
||||
return path.iscppfile(filecfg.abspath)
|
||||
end
|
||||
|
||||
local function getFileDependencies(cfg)
|
||||
local dependencies = {}
|
||||
if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then
|
||||
dependencies = {"prebuild_" .. get_key(cfg)}
|
||||
end
|
||||
for i = 1, #cfg.dependson do
|
||||
|
||||
local dependpostfix = ""
|
||||
if cfg.platform then
|
||||
dependpostfix = "_" .. cfg.platform
|
||||
end
|
||||
|
||||
table.insert(dependencies, cfg.dependson[i] .. "_" .. cfg.buildcfg .. dependpostfix)
|
||||
end
|
||||
return dependencies
|
||||
end
|
||||
|
||||
local function getcflags(toolset, cfg, filecfg)
|
||||
p.escaper(ninja.shesc)
|
||||
local buildopt = ninja.list(filecfg.buildoptions)
|
||||
local cppflags = ninja.list(toolset.getcppflags(filecfg))
|
||||
local cflags = ninja.list(toolset.getcflags(filecfg))
|
||||
local defines = ninja.list(table.join(toolset.getdefines(filecfg.defines, filecfg), toolset.getundefines(filecfg.undefines)))
|
||||
local includes = ninja.list(toolset.getincludedirs(cfg, filecfg.includedirs, filecfg.externalincludedirs, filecfg.frameworkdirs, filecfg.includedirsafter))
|
||||
local forceincludes = ninja.list(toolset.getforceincludes(cfg))
|
||||
p.escaper(nil)
|
||||
|
||||
return buildopt .. cppflags .. cflags .. defines .. includes .. forceincludes
|
||||
end
|
||||
|
||||
local function getcxxflags(toolset, cfg, filecfg)
|
||||
p.escaper(ninja.shesc)
|
||||
local buildopt = ninja.list(filecfg.buildoptions)
|
||||
local cppflags = ninja.list(toolset.getcppflags(filecfg))
|
||||
local cxxflags = ninja.list(toolset.getcxxflags(filecfg))
|
||||
local defines = ninja.list(table.join(toolset.getdefines(filecfg.defines, filecfg), toolset.getundefines(filecfg.undefines)))
|
||||
local includes = ninja.list(toolset.getincludedirs(cfg, filecfg.includedirs, filecfg.externalincludedirs, filecfg.frameworkdirs, filecfg.includedirsafter))
|
||||
local forceincludes = ninja.list(toolset.getforceincludes(cfg))
|
||||
p.escaper(nil)
|
||||
|
||||
return buildopt .. cppflags .. cxxflags .. defines .. includes .. forceincludes
|
||||
end
|
||||
|
||||
local function getldflags(toolset, cfg)
|
||||
local ldflags = ninja.list(table.join(toolset.getLibraryDirectories(cfg),
|
||||
toolset.getrunpathdirs(cfg, table.join(cfg.runpathdirs, config.getsiblingtargetdirs(cfg))),
|
||||
toolset.getldflags(cfg), cfg.linkoptions))
|
||||
|
||||
-- experimental feature, change install_name of shared libs
|
||||
--if (toolset == p.tools.clang) and (cfg.kind == p.SHAREDLIB) and ninja.endsWith(cfg.buildtarget.name, ".dylib") then
|
||||
-- ldflags = ldflags .. " -install_name " .. cfg.buildtarget.name
|
||||
--end
|
||||
|
||||
return ldflags
|
||||
end
|
||||
|
||||
local function getresflags(toolset, cfg, filecfg)
|
||||
p.escaper(ninja.shesc)
|
||||
local defines = ninja.list(toolset.getdefines(table.join(filecfg.defines, filecfg.resdefines), filecfg))
|
||||
local includes = ninja.list(toolset.getincludedirs(cfg, table.join(filecfg.externalincludedirs, filecfg.includedirsafter, filecfg.includedirs, filecfg.resincludedirs), {}, {}, {}))
|
||||
local options = ninja.list(cfg.resoptions)
|
||||
p.escaper(nil)
|
||||
|
||||
return defines .. includes .. options
|
||||
end
|
||||
|
||||
local function prebuild_rule(cfg)
|
||||
if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then
|
||||
local commands = {}
|
||||
if cfg.prebuildmessage then
|
||||
commands = {os.translateCommandsAndPaths("{ECHO} " .. cfg.prebuildmessage, cfg.workspace.basedir, cfg.workspace.location)}
|
||||
end
|
||||
commands = table.join(commands, os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.workspace.basedir, cfg.workspace.location))
|
||||
if (#commands > 1) then
|
||||
commands = 'sh -c ' .. ninja.quote(table.implode(commands,"","",";"))
|
||||
else
|
||||
commands = commands[1]
|
||||
end
|
||||
p.outln("rule run_prebuild")
|
||||
p.outln(" command = " .. commands)
|
||||
p.outln(" description = prebuild")
|
||||
p.outln("")
|
||||
end
|
||||
end
|
||||
|
||||
local function prelink_rule(cfg)
|
||||
if #cfg.prelinkcommands > 0 or cfg.prelinkmessage then
|
||||
local commands = {}
|
||||
if cfg.prelinkmessage then
|
||||
commands = {os.translateCommandsAndPaths("{ECHO} " .. cfg.prelinkmessage, cfg.workspace.basedir, cfg.workspace.location)}
|
||||
end
|
||||
commands = table.join(commands, os.translateCommandsAndPaths(cfg.prelinkcommands, cfg.workspace.basedir, cfg.workspace.location))
|
||||
if (#commands > 1) then
|
||||
commands = 'sh -c ' .. ninja.quote(table.implode(commands,"","",";"))
|
||||
else
|
||||
commands = commands[1]
|
||||
end
|
||||
p.outln("rule run_prelink")
|
||||
p.outln(" command = " .. commands)
|
||||
p.outln(" description = prelink")
|
||||
p.outln("")
|
||||
end
|
||||
end
|
||||
|
||||
local function postbuild_rule(cfg)
|
||||
if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then
|
||||
local commands = {}
|
||||
if cfg.postbuildmessage then
|
||||
commands = {os.translateCommandsAndPaths("{ECHO} " .. cfg.postbuildmessage, cfg.workspace.basedir, cfg.workspace.location)}
|
||||
end
|
||||
commands = table.join(commands, os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.workspace.basedir, cfg.workspace.location))
|
||||
if (#commands > 1) then
|
||||
commands = 'sh -c ' .. ninja.quote(table.implode(commands,"","",";"))
|
||||
else
|
||||
commands = commands[1]
|
||||
end
|
||||
p.outln("rule run_postbuild")
|
||||
p.outln(" command = " .. commands)
|
||||
p.outln(" description = postbuild")
|
||||
p.outln("")
|
||||
end
|
||||
end
|
||||
|
||||
local function c_cpp_compilation_rules(cfg, toolset, pch)
|
||||
---------------------------------------------------- figure out toolset executables
|
||||
local cc = toolset.gettoolname(cfg, "cc")
|
||||
local cxx = toolset.gettoolname(cfg, "cxx")
|
||||
local ar = toolset.gettoolname(cfg, "ar")
|
||||
local link = toolset.gettoolname(cfg, iif(cfg.language == "C", "cc", "cxx"))
|
||||
local rc = toolset.gettoolname(cfg, "rc")
|
||||
|
||||
-- all paths need to be relative to the workspace output location,
|
||||
-- and not relative to the project output location.
|
||||
-- override the toolset getrelative function to achieve this
|
||||
|
||||
local getrelative = p.tools.getrelative
|
||||
p.tools.getrelative = function(cfg, value)
|
||||
return p.workspace.getrelative(cfg.workspace, value)
|
||||
end
|
||||
|
||||
local all_cflags = getcflags(toolset, cfg, cfg)
|
||||
local all_cxxflags = getcxxflags(toolset, cfg, cfg)
|
||||
local all_ldflags = getldflags(toolset, cfg)
|
||||
local all_resflags = getresflags(toolset, cfg, cfg)
|
||||
|
||||
if toolset == p.tools.msc then
|
||||
p.outln("CFLAGS=" .. all_cflags)
|
||||
p.outln("rule cc")
|
||||
p.outln(" command = " .. cc .. " $CFLAGS" .. " /nologo /showIncludes -c /Tc$in /Fo$out")
|
||||
p.outln(" description = cc $out")
|
||||
p.outln(" deps = msvc")
|
||||
p.outln("")
|
||||
p.outln("CXXFLAGS=" .. all_cxxflags)
|
||||
p.outln("rule cxx")
|
||||
p.outln(" command = " .. cxx .. " $CXXFLAGS" .. " /nologo /showIncludes -c /Tp$in /Fo$out")
|
||||
p.outln(" description = cxx $out")
|
||||
p.outln(" deps = msvc")
|
||||
p.outln("")
|
||||
p.outln("CFLAGS=" .. all_cflags)
|
||||
p.outln("rule clangtidy_cc")
|
||||
p.outln(" command = clang-tidy $in -- -x c $CFLAGS &&$")
|
||||
p.outln(" " .. cc .. " $CFLAGS" .. " /nologo /showIncludes -c /Tc$in /Fo$out")
|
||||
p.outln(" description = cc $out")
|
||||
p.outln(" deps = msvc")
|
||||
p.outln("")
|
||||
p.outln("CXXFLAGS=" .. all_cxxflags)
|
||||
p.outln("rule clangtidy_cxx")
|
||||
p.outln(" command = clang-tidy $in -- -x c++ $CFLAGS &&$")
|
||||
p.outln(" " .. cxx .. " $CXXFLAGS" .. " /nologo /showIncludes -c /Tp$in /Fo$out")
|
||||
p.outln(" description = cxx $out")
|
||||
p.outln(" deps = msvc")
|
||||
p.outln("")
|
||||
p.outln("RESFLAGS = " .. all_resflags)
|
||||
p.outln("rule rc")
|
||||
p.outln(" command = " .. rc .. " /nologo /fo$out $in $RESFLAGS")
|
||||
p.outln(" description = rc $out")
|
||||
p.outln("")
|
||||
if cfg.kind == p.STATICLIB then
|
||||
p.outln("rule ar")
|
||||
p.outln(" command = " .. ar .. " $in /nologo -OUT:$out")
|
||||
p.outln(" description = ar $out")
|
||||
p.outln("")
|
||||
else
|
||||
p.outln("rule link")
|
||||
p.outln(" command = " .. link .. " $in" .. ninja.list(ninja.shesc(toolset.getlinks(cfg, true))) .. " /link" .. all_ldflags .. " /nologo /out:$out")
|
||||
p.outln(" description = link $out")
|
||||
p.outln("")
|
||||
end
|
||||
elseif toolset == p.tools.clang or toolset == p.tools.gcc or toolset == p.tools.emcc then
|
||||
local force_include_pch = ""
|
||||
if pch then
|
||||
force_include_pch = " -include " .. ninja.shesc(pch.placeholder)
|
||||
p.outln("rule build_pch")
|
||||
p.outln(" command = " .. iif(cfg.language == "C", cc .. all_cflags .. " -x c-header", cxx .. all_cxxflags .. " -x c++-header") .. " -H -MF $out.d -c -o $out $in")
|
||||
p.outln(" description = build_pch $out")
|
||||
p.outln(" depfile = $out.d")
|
||||
p.outln(" deps = gcc")
|
||||
end
|
||||
p.outln("CFLAGS=" .. all_cflags)
|
||||
p.outln("rule cc")
|
||||
p.outln(" command = " .. cc .. " $CFLAGS" .. force_include_pch .. " -x c -MF $out.d -c -o $out $in")
|
||||
p.outln(" description = cc $out")
|
||||
p.outln(" depfile = $out.d")
|
||||
p.outln(" deps = gcc")
|
||||
p.outln("")
|
||||
p.outln("CXXFLAGS=" .. all_cxxflags)
|
||||
p.outln("rule cxx")
|
||||
p.outln(" command = " .. cxx .. " $CXXFLAGS" .. force_include_pch .. " -x c++ -MF $out.d -c -o $out $in")
|
||||
p.outln(" description = cxx $out")
|
||||
p.outln(" depfile = $out.d")
|
||||
p.outln(" deps = gcc")
|
||||
p.outln("")
|
||||
p.outln("CFLAGS=" .. all_cflags)
|
||||
p.outln("rule clangtidy_cc")
|
||||
p.outln(" command = clang-tidy $in -- -x c $CFLAGS" .. force_include_pch .. " &&$")
|
||||
p.outln(" " .. cc .. " $CFLAGS" .. force_include_pch .. " -x c -MF $out.d -c -o $out $in")
|
||||
p.outln(" description = cc $out")
|
||||
p.outln(" depfile = $out.d")
|
||||
p.outln(" deps = gcc")
|
||||
p.outln("")
|
||||
p.outln("CXXFLAGS=" .. all_cxxflags)
|
||||
p.outln("rule clangtidy_cxx")
|
||||
p.outln(" command = clang-tidy $in -- -x c++ $CFLAGS" .. force_include_pch .. " &&$")
|
||||
p.outln(" " .. cxx .. " $CXXFLAGS" .. force_include_pch .. " -x c++ -MF $out.d -c -o $out $in")
|
||||
p.outln(" description = cxx $out")
|
||||
p.outln(" depfile = $out.d")
|
||||
p.outln(" deps = gcc")
|
||||
p.outln("")
|
||||
p.outln("RESFLAGS = " .. all_resflags)
|
||||
|
||||
if rc then
|
||||
p.outln("rule rc")
|
||||
p.outln(" command = " .. rc .. " -i $in -o $out $RESFLAGS")
|
||||
p.outln(" description = rc $out")
|
||||
p.outln("")
|
||||
end
|
||||
|
||||
if ar and cfg.kind == p.STATICLIB then
|
||||
p.outln("rule ar")
|
||||
p.outln(" command = " .. ar .. " rcs $out $in")
|
||||
p.outln(" description = ar $out")
|
||||
p.outln("")
|
||||
else
|
||||
local groups = iif(cfg.linkgroups == premake.ON, {"-Wl,--start-group ", " -Wl,--end-group"}, {"", ""})
|
||||
p.outln("rule link")
|
||||
p.outln(" command = " .. link .. " -o $out " .. groups[1] .. "$in" .. ninja.list(ninja.shesc(toolset.getlinks(cfg, true, true))) .. all_ldflags .. groups[2])
|
||||
p.outln(" description = link $out")
|
||||
p.outln("")
|
||||
end
|
||||
end
|
||||
|
||||
p.tools.getrelative = getrelative
|
||||
end
|
||||
|
||||
local function custom_command_rule()
|
||||
p.outln("rule custom_command")
|
||||
p.outln(" command = $CUSTOM_COMMAND")
|
||||
p.outln(" description = $CUSTOM_DESCRIPTION")
|
||||
p.outln("")
|
||||
end
|
||||
|
||||
local function copy_rule()
|
||||
p.outln("rule copy")
|
||||
p.outln(" command = " .. os.translateCommands("{COPYFILE} $in $out"))
|
||||
p.outln(" description = copy $in $out")
|
||||
p.outln("")
|
||||
end
|
||||
|
||||
local function collect_generated_files(prj, cfg)
|
||||
local generated_files = {}
|
||||
tree.traverse(project.getsourcetree(prj), {
|
||||
onleaf = function(node, depth)
|
||||
function append_to_generated_files(filecfg)
|
||||
local outputs = project.getrelative(prj.workspace, filecfg.buildoutputs)
|
||||
generated_files = table.join(generated_files, outputs)
|
||||
end
|
||||
local filecfg = fileconfig.getconfig(node, cfg)
|
||||
if not filecfg or filecfg.flags.ExcludeFromBuild then
|
||||
return
|
||||
end
|
||||
local rule = p.global.getRuleForFile(node.name, prj.rules)
|
||||
if fileconfig.hasCustomBuildRule(filecfg) then
|
||||
append_to_generated_files(filecfg)
|
||||
elseif rule then
|
||||
local environ = table.shallowcopy(filecfg.environ)
|
||||
|
||||
if rule.propertydefinition then
|
||||
p.rule.prepareEnvironment(rule, environ, cfg)
|
||||
p.rule.prepareEnvironment(rule, environ, filecfg)
|
||||
end
|
||||
local rulecfg = p.context.extent(rule, environ)
|
||||
append_to_generated_files(rulecfg)
|
||||
end
|
||||
end,
|
||||
}, false, 1)
|
||||
return generated_files
|
||||
end
|
||||
|
||||
local function pch_build(cfg, pch)
|
||||
local pch_dependency = {}
|
||||
if pch then
|
||||
pch_dependency = { pch.gch }
|
||||
ninja.add_build(cfg, pch.gch, {}, "build_pch", {pch.input}, {}, {}, {})
|
||||
end
|
||||
return pch_dependency
|
||||
end
|
||||
|
||||
local function custom_command_build(prj, cfg, filecfg, filename, file_dependencies)
|
||||
local outputs = project.getrelative(prj.workspace, filecfg.buildoutputs)
|
||||
local output = outputs[1]
|
||||
table.remove(outputs, 1)
|
||||
local commands = {}
|
||||
if filecfg.buildmessage then
|
||||
commands = {os.translateCommandsAndPaths("{ECHO} " .. filecfg.buildmessage, prj.workspace.basedir, prj.workspace.location)}
|
||||
end
|
||||
commands = table.join(commands, os.translateCommandsAndPaths(filecfg.buildcommands, prj.workspace.basedir, prj.workspace.location))
|
||||
if (#commands > 1) then
|
||||
commands = 'sh -c ' .. ninja.quote(table.implode(commands,"","",";"))
|
||||
else
|
||||
commands = commands[1]
|
||||
end
|
||||
|
||||
ninja.add_build(cfg, output, outputs, "custom_command", {filename}, project.getrelative(prj.workspace, filecfg.buildinputs), file_dependencies,
|
||||
{"CUSTOM_COMMAND = " .. commands, "CUSTOM_DESCRIPTION = custom build " .. ninja.shesc(output)})
|
||||
end
|
||||
|
||||
local function compile_file_build(cfg, filecfg, toolset, pch_dependency, regular_file_dependencies, objfiles, extrafiles)
|
||||
local obj_dir = project.getrelative(cfg.workspace, cfg.objdir)
|
||||
local filepath = project.getrelative(cfg.workspace, filecfg.abspath)
|
||||
local has_custom_settings = fileconfig.hasFileSettings(filecfg)
|
||||
local use_clangtidy = filecfg.clangtidy or (filecfg.clangtidy == nil and cfg.clangtidy)
|
||||
|
||||
if filecfg.buildaction == "None" then
|
||||
return
|
||||
elseif filecfg.buildaction == "Copy" then
|
||||
local target = project.getrelative(cfg.workspace, path.join(cfg.targetdir, filecfg.name))
|
||||
ninja.add_build(cfg, target, {}, "copy", {filepath}, {}, {}, {})
|
||||
extrafiles[#extrafiles + 1] = target
|
||||
elseif shouldcompileasc(filecfg) then
|
||||
local objfilename = obj_dir .. "/" .. filecfg.objname .. (toolset.objectextension or ".o")
|
||||
objfiles[#objfiles + 1] = objfilename
|
||||
local cflags = {}
|
||||
if has_custom_settings then
|
||||
cflags = {"CFLAGS = $CFLAGS " .. getcflags(toolset, cfg, filecfg)}
|
||||
end
|
||||
ninja.add_build(cfg, objfilename, {}, iif(use_clangtidy, "clangtidy_cc", "cc"), {filepath}, pch_dependency, regular_file_dependencies, cflags)
|
||||
elseif shouldcompileascpp(filecfg) then
|
||||
local objfilename = obj_dir .. "/" .. filecfg.objname .. (toolset.objectextension or ".o")
|
||||
objfiles[#objfiles + 1] = objfilename
|
||||
local cxxflags = {}
|
||||
if has_custom_settings then
|
||||
cxxflags = {"CXXFLAGS = $CXXFLAGS " .. getcxxflags(toolset, cfg, filecfg)}
|
||||
end
|
||||
ninja.add_build(cfg, objfilename, {}, iif(use_clangtidy, "clangtidy_cxx", "cxx"), {filepath}, pch_dependency, regular_file_dependencies, cxxflags)
|
||||
elseif path.isresourcefile(filecfg.abspath) then
|
||||
local objfilename = obj_dir .. "/" .. filecfg.basename .. ".res"
|
||||
objfiles[#objfiles + 1] = objfilename
|
||||
local resflags = {}
|
||||
if has_custom_settings then
|
||||
resflags = {"RESFLAGS = $RESFLAGS " .. getresflags(toolset, cfg, filecfg)}
|
||||
end
|
||||
local rc = toolset.gettoolname(cfg, "rc")
|
||||
if rc then
|
||||
ninja.add_build(cfg, objfilename, {}, "rc", {filepath}, {}, {}, resflags)
|
||||
else
|
||||
p.warnOnce(filepath, string.format("Ignored resource: '%s'", filepath))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function files_build(prj, cfg, toolset, pch_dependency, regular_file_dependencies, file_dependencies)
|
||||
local objfiles = {}
|
||||
local extrafiles = {}
|
||||
tree.traverse(project.getsourcetree(prj), {
|
||||
onleaf = function(node, depth)
|
||||
local filecfg = fileconfig.getconfig(node, cfg)
|
||||
if not filecfg or filecfg.flags.ExcludeFromBuild then
|
||||
return
|
||||
end
|
||||
local rule = p.global.getRuleForFile(node.name, prj.rules)
|
||||
local filepath = project.getrelative(cfg.workspace, node.abspath)
|
||||
|
||||
if fileconfig.hasCustomBuildRule(filecfg) then
|
||||
custom_command_build(prj, cfg, filecfg, filepath, file_dependencies)
|
||||
elseif rule then
|
||||
local environ = table.shallowcopy(filecfg.environ)
|
||||
|
||||
if rule.propertydefinition then
|
||||
p.rule.prepareEnvironment(rule, environ, cfg)
|
||||
p.rule.prepareEnvironment(rule, environ, filecfg)
|
||||
end
|
||||
local rulecfg = p.context.extent(rule, environ)
|
||||
custom_command_build(prj, cfg, rulecfg, filepath, file_dependencies)
|
||||
else
|
||||
compile_file_build(cfg, filecfg, toolset, pch_dependency, regular_file_dependencies, objfiles, extrafiles)
|
||||
end
|
||||
end,
|
||||
}, false, 1)
|
||||
p.outln("")
|
||||
|
||||
return objfiles, extrafiles
|
||||
end
|
||||
|
||||
local function generated_files_build(cfg, generated_files, key)
|
||||
local final_dependency = {}
|
||||
if #generated_files > 0 then
|
||||
p.outln("# generated files")
|
||||
ninja.add_build(cfg, "generated_files_" .. key, {}, "phony", generated_files, {}, {}, {})
|
||||
final_dependency = {"generated_files_" .. key}
|
||||
end
|
||||
return final_dependency
|
||||
end
|
||||
|
||||
-- generate project + config build file
|
||||
function ninja.generateProjectCfg(cfg)
|
||||
local oldGetDefaultSeparator = path.getDefaultSeparator
|
||||
path.getDefaultSeparator = function() return "/" end
|
||||
|
||||
local prj = cfg.project
|
||||
local key = get_key(cfg)
|
||||
local toolset, toolset_version = p.tools.canonical(cfg.toolset)
|
||||
|
||||
if not toolset then
|
||||
p.error("Unknown toolset " .. cfg.toolset)
|
||||
end
|
||||
|
||||
-- Some toolset fixes
|
||||
cfg.gccprefix = cfg.gccprefix or ""
|
||||
|
||||
p.outln("# project build file")
|
||||
p.outln("# generated with premake ninja")
|
||||
p.outln("")
|
||||
|
||||
-- premake-ninja relies on scoped rules
|
||||
-- and they were added in ninja v1.6
|
||||
p.outln("ninja_required_version = 1.6")
|
||||
p.outln("")
|
||||
|
||||
local is_c_or_cpp = cfg.language == p.C or cfg.language == p.CPP;
|
||||
|
||||
---------------------------------------------------- figure out settings
|
||||
local pch = nil
|
||||
if is_c_or_cpp then
|
||||
if toolset ~= p.tools.msc then
|
||||
pch = p.tools.gcc.getpch(cfg)
|
||||
if pch then
|
||||
pch = {
|
||||
input = pch,
|
||||
placeholder = project.getrelative(cfg.workspace, path.join(cfg.objdir, path.getname(pch))),
|
||||
gch = project.getrelative(cfg.workspace, path.join(cfg.objdir, path.getname(pch) .. ".gch"))
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------- write rules
|
||||
p.outln("# core rules for " .. cfg.name)
|
||||
prebuild_rule(cfg)
|
||||
prelink_rule(cfg)
|
||||
postbuild_rule(cfg)
|
||||
|
||||
if is_c_or_cpp then
|
||||
c_cpp_compilation_rules(cfg, toolset, pch)
|
||||
else
|
||||
local handler = ninja.handlers[cfg.language]
|
||||
if not handler then
|
||||
p.error("expected registered ninja handler action for target " .. cfg.language)
|
||||
end
|
||||
handler.compilation_rules(cfg, toolset)
|
||||
end
|
||||
|
||||
copy_rule()
|
||||
custom_command_rule()
|
||||
|
||||
---------------------------------------------------- build all files
|
||||
p.outln("# build files")
|
||||
|
||||
local pch_dependency = is_c_or_cpp and pch_build(cfg, pch) or {}
|
||||
|
||||
local generated_files = collect_generated_files(prj, cfg)
|
||||
|
||||
local file_dependencies = getFileDependencies(cfg)
|
||||
local regular_file_dependencies = table.join(iif(#generated_files > 0, {"generated_files_" .. key}, {}), file_dependencies)
|
||||
|
||||
local obj_dir = project.getrelative(cfg.workspace, cfg.objdir)
|
||||
local objfiles, extrafiles = files_build(prj, cfg, toolset, pch_dependency, regular_file_dependencies, file_dependencies)
|
||||
local final_dependency = generated_files_build(cfg, generated_files, key)
|
||||
|
||||
---------------------------------------------------- build final target
|
||||
if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then
|
||||
p.outln("# prebuild")
|
||||
ninja.add_build(cfg, "prebuild_" .. get_key(cfg), {}, "run_prebuild", {}, {}, {}, {})
|
||||
end
|
||||
local prelink_dependency = {}
|
||||
if #cfg.prelinkcommands > 0 or cfg.prelinkmessage then
|
||||
p.outln("# prelink")
|
||||
ninja.add_build(cfg, "prelink_" .. get_key(cfg), {}, "run_prelink", {}, objfiles, final_dependency, {})
|
||||
prelink_dependency = { "prelink_" .. get_key(cfg) }
|
||||
end
|
||||
if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then
|
||||
p.outln("# postbuild")
|
||||
ninja.add_build(cfg, "postbuild_" .. get_key(cfg), {}, "run_postbuild", {}, {ninja.outputFilename(cfg)}, {}, {})
|
||||
end
|
||||
|
||||
if is_c_or_cpp then
|
||||
-- we don't pass getlinks(cfg) through dependencies
|
||||
-- because system libraries are often not in PATH so ninja can't find them
|
||||
local libs = table.translate(config.getlinks(cfg, "siblings", "fullpath"),
|
||||
function (p) return project.getrelative(cfg.workspace, path.join(cfg.project.location, p)) end)
|
||||
local cfg_output = ninja.outputFilename(cfg)
|
||||
local extra_outputs = {}
|
||||
local command_rule = ""
|
||||
if cfg.kind == p.STATICLIB then
|
||||
p.outln("# link static lib")
|
||||
command_rule = "ar"
|
||||
elseif cfg.kind == p.SHAREDLIB then
|
||||
p.outln("# link shared lib")
|
||||
command_rule = "link"
|
||||
extra_outputs = iif(os.target() == "windows", {path.replaceextension(cfg_output, ".lib"), path.replaceextension(cfg_output, ".exp")}, {})
|
||||
elseif (cfg.kind == p.CONSOLEAPP) or (cfg.kind == p.WINDOWEDAPP) then
|
||||
p.outln("# link executable")
|
||||
command_rule = "link"
|
||||
else
|
||||
p.error("ninja action doesn't support this kind of target " .. cfg.kind)
|
||||
end
|
||||
|
||||
local deps = table.join(final_dependency, extrafiles, prelink_dependency)
|
||||
ninja.add_build(cfg, cfg_output, extra_outputs, command_rule, table.join(objfiles, libs), {}, deps, {})
|
||||
outputs = {cfg_output}
|
||||
else
|
||||
local handler = ninja.handlers[cfg.language]
|
||||
if not handler then
|
||||
p.error("expected registered ninja handler action for target " .. cfg.language)
|
||||
end
|
||||
outputs = handler.target_rules(cfg, toolset)
|
||||
end
|
||||
|
||||
p.outln("")
|
||||
if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then
|
||||
ninja.add_build(cfg, key, {}, "phony", {"postbuild_" .. get_key(cfg)}, {}, {}, {})
|
||||
else
|
||||
ninja.add_build(cfg, key, {}, "phony", outputs, {}, {}, {})
|
||||
end
|
||||
p.outln("")
|
||||
|
||||
path.getDefaultSeparator = oldGetDefaultSeparator
|
||||
end
|
||||
|
||||
-- return name of output binary relative to build folder
|
||||
function ninja.outputFilename(cfg)
|
||||
return project.getrelative(cfg.workspace, cfg.buildtarget.directory) .. "/" .. cfg.buildtarget.name
|
||||
end
|
||||
|
||||
-- return name of build file for configuration
|
||||
function ninja.projectCfgFilename(cfg, relative)
|
||||
if relative ~= nil then
|
||||
relative = project.getrelative(cfg.workspace, cfg.location) .. "/"
|
||||
else
|
||||
relative = ""
|
||||
end
|
||||
return relative .. get_key(cfg, cfg.project.filename) .. ".ninja"
|
||||
end
|
||||
|
||||
-- check if string starts with string
|
||||
function ninja.startsWith(str, starts)
|
||||
return str:sub(0, starts:len()) == starts
|
||||
end
|
||||
|
||||
-- check if string ends with string
|
||||
function ninja.endsWith(str, ends)
|
||||
return str:sub(-ends:len()) == ends
|
||||
end
|
||||
|
||||
-- generate all build files for every project configuration
|
||||
function ninja.generateProject(prj)
|
||||
if not ninja.can_generate(prj) then
|
||||
return
|
||||
end
|
||||
for cfg in project.eachconfig(prj) do
|
||||
p.generate(cfg, ninja.projectCfgFilename(cfg), ninja.generateProjectCfg)
|
||||
end
|
||||
end
|
||||
|
||||
include("_preload.lua")
|
||||
|
||||
return ninja
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include "test1.h"
|
||||
#include "test2.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("hello world !\n");
|
||||
test1();
|
||||
test2();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj"
|
||||
kind "ConsoleApp"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"**.cpp", "**.c", "**.h"}
|
||||
includedirs {"test1", "test2"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test1();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test2()
|
||||
{
|
||||
printf("hello from test2 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void test2();
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include <stdio.h>
|
||||
#include "test1.h"
|
||||
#include "test2.h"
|
||||
#include "test 3.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("hello world !\n");
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj"
|
||||
kind "ConsoleApp"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"**.cpp", "**.c", "**.h"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test 3.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test3()
|
||||
{
|
||||
printf("hello from test3 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test3();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test1();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test2()
|
||||
{
|
||||
printf("hello from test2 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void test2();
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
# unittests for premake-ninja
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import shutil
|
||||
import platform
|
||||
import unittest
|
||||
import subprocess
|
||||
|
||||
# we are changing working directory often in this tests, so let's save current one
|
||||
current_cwd = os.getcwd()
|
||||
|
||||
# if set, will override compiler name when premake is executed
|
||||
override_compiler = None
|
||||
|
||||
# finds the file in path
|
||||
def which(cmd, mode = os.F_OK | os.X_OK, path = None):
|
||||
if sys.version_info[0:2] >= (3, 3):
|
||||
return shutil.which(cmd, mode, path)
|
||||
else:
|
||||
def _access_check(fn, mode):
|
||||
return (os.path.exists(fn) and os.access(fn, mode)
|
||||
and not os.path.isdir(fn))
|
||||
|
||||
if os.path.dirname(cmd):
|
||||
if _access_check(cmd, mode):
|
||||
return cmd
|
||||
return None
|
||||
|
||||
if path is None:
|
||||
path = os.environ.get("PATH", os.defpath)
|
||||
if not path:
|
||||
return None
|
||||
path = path.split(os.pathsep)
|
||||
|
||||
if sys.platform == "win32":
|
||||
if not os.curdir in path:
|
||||
path.insert(0, os.curdir)
|
||||
pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
|
||||
if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
|
||||
files = [cmd]
|
||||
else:
|
||||
files = [cmd + ext for ext in pathext]
|
||||
else:
|
||||
files = [cmd]
|
||||
|
||||
seen = set()
|
||||
for dir in path:
|
||||
normdir = os.path.normcase(dir)
|
||||
if not normdir in seen:
|
||||
seen.add(normdir)
|
||||
for thefile in files:
|
||||
name = os.path.join(dir, thefile)
|
||||
if _access_check(name, mode):
|
||||
return name
|
||||
return None
|
||||
|
||||
# ----------------------------------------------------- helper class
|
||||
class Helper(unittest.TestCase):
|
||||
# removes build directory in test folder
|
||||
def clear(self, build_dir):
|
||||
if os.path.exists(build_dir):
|
||||
shutil.rmtree(build_dir)
|
||||
|
||||
# enters test, and clears it
|
||||
def enter_test(self, test, build_dir = "build"):
|
||||
self.build_dir = build_dir
|
||||
os.chdir(current_cwd) # if previous test failed then we need to restore cwd
|
||||
os.chdir(test)
|
||||
self.clear(build_dir)
|
||||
|
||||
# clears test and exit from it
|
||||
def exit_test(self, build_dir = "build"):
|
||||
# for some reason call/check_call are not waiting for executable to completely finish
|
||||
# so let's wait a bit so we can remove folder safely
|
||||
time.sleep(0.3)
|
||||
self.clear(build_dir)
|
||||
os.chdir(current_cwd)
|
||||
|
||||
# call premake in the test
|
||||
def premake(self):
|
||||
if override_compiler:
|
||||
args = ["premake5", "--scripts=../../..", "--cc=" + override_compiler, "ninja"]
|
||||
if override_compiler == "emcc":
|
||||
args += ["--os=emscripten"]
|
||||
self.assertEqual(subprocess.call(args), 0, "looks like premake failed")
|
||||
else:
|
||||
self.assertEqual(subprocess.call(["premake5", "--scripts=../../..", "ninja"]), 0, "looks like premake failed")
|
||||
|
||||
# call ninja in the test
|
||||
def ninja(self, target = None):
|
||||
args = ["ninja", "-C", "build"]
|
||||
if target is not None:
|
||||
args.append(target)
|
||||
self.assertEqual(subprocess.call(args), 0, "looks like ninja failed")
|
||||
|
||||
# get out name with ext and prefix
|
||||
def out_name(self, path, ext = None, prefix = None):
|
||||
if (ext == None) and (prefix == None):
|
||||
return path
|
||||
base_path = os.path.dirname(path)
|
||||
base_name_and_ext = os.path.splitext(os.path.basename(path))
|
||||
if prefix == None:
|
||||
prefix = ""
|
||||
if ext == None:
|
||||
ext = base_name_and_ext[1]
|
||||
return base_path + "/" + prefix + base_name_and_ext[0] + ext
|
||||
|
||||
# check if executable exist
|
||||
def out_exist(self, path):
|
||||
print(f"Looking for {path} in {os.listdir(os.path.dirname(path))}")
|
||||
sys.stdout.flush()
|
||||
self.assertTrue(
|
||||
os.path.exists(path) or
|
||||
os.path.exists(self.out_name(path, ".exe")) or
|
||||
os.path.exists(self.out_name(path, ".app")) or
|
||||
os.path.exists(self.out_name(path, ".lib")) or
|
||||
os.path.exists(self.out_name(path, ".a", "lib")) or
|
||||
os.path.exists(self.out_name(path, ".dll")) or
|
||||
os.path.exists(self.out_name(path, ".so", "lib")) or
|
||||
os.path.exists(self.out_name(path, ".dylib", "lib")) or
|
||||
os.path.exists(self.out_name(path, ".wasm"))
|
||||
)
|
||||
print(f"Found {path}")
|
||||
sys.stdout.flush()
|
||||
# check if executable doesn't exist
|
||||
def out_not_exist(self, path):
|
||||
self.assertFalse(
|
||||
os.path.exists(path) or
|
||||
os.path.exists(self.out_name(path, ".exe")) or
|
||||
os.path.exists(self.out_name(path, ".app")) or
|
||||
os.path.exists(self.out_name(path, ".lib")) or
|
||||
os.path.exists(self.out_name(path, ".a", "lib")) or
|
||||
os.path.exists(self.out_name(path, ".dll")) or
|
||||
os.path.exists(self.out_name(path, ".so", "lib")) or
|
||||
os.path.exists(self.out_name(path, ".dylib", "lib")) or
|
||||
os.path.exists(self.out_name(path, ".wasm"))
|
||||
)
|
||||
|
||||
# check if executable exist
|
||||
def exe(self, path):
|
||||
if os.path.exists(path):
|
||||
current_cwd = os.getcwd()
|
||||
os.chdir(self.build_dir)
|
||||
executable = os.path.relpath(path, self.build_dir)
|
||||
subprocess.check_call([executable], env={'LD_LIBRARY_PATH': os.path.dirname(executable), 'DYLD_LIBRARY_PATH': os.path.dirname(executable)})
|
||||
os.chdir(current_cwd)
|
||||
elif os.path.exists(path + ".exe"):
|
||||
subprocess.check_call([path + ".exe"])
|
||||
elif os.path.exists(path + ".app"):
|
||||
subprocess.check_call([path + ".app"])
|
||||
elif os.path.exists(self.out_name(path, ".lib")) or os.path.exists(self.out_name(path, ".a", "lib")) or os.path.exists(self.out_name(path, ".dll")) or os.path.exists(self.out_name(path, ".so", "lib")) or os.path.exists(self.out_name(path, ".dylib", "lib")):
|
||||
pass
|
||||
else:
|
||||
self.assertTrue(False, "executable '" + path + "' doesn't exist")
|
||||
|
||||
# check basic flow, run debug and release executables
|
||||
def check_basics(self, out_debug, out_release, build_dir = "build"):
|
||||
# build dir should not exist before premake is called
|
||||
self.assertFalse(os.path.exists(build_dir))
|
||||
|
||||
# call premake
|
||||
# build dir should exist afterwards, but executables shouldn't
|
||||
self.premake()
|
||||
self.assertTrue(os.path.exists(build_dir))
|
||||
self.out_not_exist(out_debug)
|
||||
self.out_not_exist(out_release)
|
||||
|
||||
# call ninja, by default ninja should build debug target
|
||||
# so debug executable should exist, and release shouldn't
|
||||
self.ninja()
|
||||
self.out_exist(out_debug)
|
||||
self.out_not_exist(out_release)
|
||||
|
||||
# let's build debug target explicitly, and still release executable shouldn't exist
|
||||
self.ninja("debug")
|
||||
self.out_exist(out_debug)
|
||||
self.out_not_exist(out_release)
|
||||
|
||||
# let's build release target explicitly, all basic executables should exist now
|
||||
self.ninja("release")
|
||||
self.out_exist(out_debug)
|
||||
self.out_exist(out_release)
|
||||
|
||||
# run executables to check if they are valid
|
||||
if override_compiler != "emcc":
|
||||
self.exe(out_debug)
|
||||
self.exe(out_release)
|
||||
|
||||
# ----------------------------------------------------- console app tests
|
||||
class TestConsoleApp(Helper):
|
||||
# test simple app
|
||||
def test_simple(self):
|
||||
self.enter_test("console_app/simple")
|
||||
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
||||
self.exit_test()
|
||||
|
||||
# test include path app
|
||||
def test_include_path(self):
|
||||
self.enter_test("console_app/includepath")
|
||||
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
||||
self.exit_test()
|
||||
|
||||
# ----------------------------------------------------- static lib tests
|
||||
class TestStaticLib(Helper):
|
||||
# test simple app
|
||||
def test_simple(self):
|
||||
self.enter_test("static_lib/simple")
|
||||
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
||||
self.exit_test()
|
||||
|
||||
# test static lib with app
|
||||
def test_withapp(self):
|
||||
self.enter_test("static_lib/withapp")
|
||||
self.check_basics("build/bin_debug/ninjatestprj_app", "build/bin_release/ninjatestprj_app")
|
||||
self.out_exist("build/bin_debug/ninjatestprj_lib test1")
|
||||
self.out_exist("build/bin_release/ninjatestprj_lib test1")
|
||||
self.out_exist("build/bin_debug/ninjatestprj_lib_test2")
|
||||
self.out_exist("build/bin_release/ninjatestprj_lib_test2")
|
||||
self.exit_test()
|
||||
|
||||
# ----------------------------------------------------- shared lib tests
|
||||
class TestSharedLib(Helper):
|
||||
# test simple app
|
||||
def test_simple(self):
|
||||
# Skip shared library tests on Emscripten since this is an advanced feature not supported by Premake yet.
|
||||
if override_compiler == "emcc":
|
||||
return
|
||||
self.enter_test("shared_lib/simple")
|
||||
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
||||
self.exit_test()
|
||||
|
||||
# test shared lib with app
|
||||
def test_withapp(self):
|
||||
# Skip shared library tests on Emscripten since this is an advanced feature not supported by Premake yet.
|
||||
if override_compiler == "emcc":
|
||||
return
|
||||
self.enter_test("shared_lib/withapp")
|
||||
self.check_basics("build/bin_debug/ninjatestprj_app", "build/bin_release/ninjatestprj_app")
|
||||
self.out_exist("build/bin_debug/ninjatestprj_lib_test1")
|
||||
self.out_exist("build/bin_release/ninjatestprj_lib_test1")
|
||||
self.out_exist("build/bin_debug/ninjatestprj_lib_test2")
|
||||
self.out_exist("build/bin_release/ninjatestprj_lib_test2")
|
||||
self.exit_test()
|
||||
|
||||
# ----------------------------------------------------- windowed app tests
|
||||
class TestWindowedApp(Helper):
|
||||
# test simple app
|
||||
def test_simple(self):
|
||||
self.enter_test("windowed_app/simple")
|
||||
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
||||
self.exit_test()
|
||||
|
||||
# ----------------------------------------------------- entry point
|
||||
if __name__ == "__main__":
|
||||
print("-------------------------- test default setup")
|
||||
r = unittest.main(exit = False)
|
||||
if not r.result.wasSuccessful():
|
||||
sys.exit(1)
|
||||
|
||||
if platform.system() == "Windows" and which("gcc"):
|
||||
print("-------------------------- found gcc on windows")
|
||||
override_compiler = "gcc"
|
||||
unittest.main()
|
||||
|
||||
if which("emcc"):
|
||||
print("-------------------------- found emcc")
|
||||
override_compiler = "emcc"
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj"
|
||||
kind "SharedLib"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"**.cpp", "**.c", "**.h"}
|
||||
defines {"DLL_EXPORT"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
TESTLIB void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef DLL_EXPORT
|
||||
#define TESTLIB __declspec(dllexport)
|
||||
#else
|
||||
#define TESTLIB __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define TESTLIB
|
||||
#endif
|
||||
|
||||
TESTLIB void test1();
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include "test1.h"
|
||||
#include "test2.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("hello world !\n");
|
||||
test1();
|
||||
test2();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj_app"
|
||||
kind "ConsoleApp"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"main.cpp"}
|
||||
includedirs {"test1", "test2"}
|
||||
links {"ninjatestprj_lib_test1", "ninjatestprj_lib_test2"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
||||
project "ninjatestprj_lib_test1"
|
||||
kind "SharedLib"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"test1/**.cpp", "test1/**.c", "test1/**.h"}
|
||||
includedirs {"test1"}
|
||||
defines {"DLL_EXPORT"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
||||
project "ninjatestprj_lib_test2"
|
||||
kind "SharedLib"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"test2/**.cpp", "test2/**.c", "test2/**.h"}
|
||||
includedirs {"test2"}
|
||||
defines {"DLL_EXPORT2"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
TESTLIB void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef DLL_EXPORT
|
||||
#define TESTLIB __declspec(dllexport)
|
||||
#else
|
||||
#define TESTLIB __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define TESTLIB
|
||||
#endif
|
||||
|
||||
TESTLIB void test1();
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
TESTLIB2 void test2()
|
||||
{
|
||||
printf("hello from test2 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef DLL_EXPORT2
|
||||
#define TESTLIB2 __declspec(dllexport)
|
||||
#else
|
||||
#define TESTLIB2 __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define TESTLIB2
|
||||
#endif
|
||||
|
||||
TESTLIB2 void test2();
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj"
|
||||
kind "StaticLib"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"**.cpp", "**.c", "**.h"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test1();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include "test1.h"
|
||||
#include "test2.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("hello world !\n");
|
||||
test1();
|
||||
test2();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj_app"
|
||||
kind "ConsoleApp"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"main.cpp"}
|
||||
includedirs {"test1", "test2"}
|
||||
links {"ninjatestprj_lib test1", "ninjatestprj_lib_test2"}
|
||||
|
||||
filter {"system:windows"}
|
||||
links { "user32", "gdi32" }
|
||||
|
||||
filter {"system:linux"}
|
||||
links { "pthread" }
|
||||
-- todo add system libs for os x and linux
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
||||
project "ninjatestprj_lib test1"
|
||||
kind "StaticLib"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"test1/**.cpp", "test1/**.c", "test1/**.h"}
|
||||
includedirs {"test1"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
||||
project "ninjatestprj_lib_test2"
|
||||
kind "StaticLib"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"test2/**.cpp", "test2/**.c", "test2/**.h"}
|
||||
includedirs {"test2"}
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test1();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test2()
|
||||
{
|
||||
printf("hello from test2 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void test2();
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
#include "test1.h"
|
||||
#include "test2.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
|
||||
#else
|
||||
int main()
|
||||
#endif
|
||||
{
|
||||
printf("hello world !\n");
|
||||
test1();
|
||||
test2();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
require "ninja"
|
||||
|
||||
solution "ninjatestsln"
|
||||
location "build"
|
||||
configurations {"debug", "release"}
|
||||
|
||||
project "ninjatestprj"
|
||||
kind "WindowedApp"
|
||||
location "build"
|
||||
language "C++"
|
||||
targetdir "build/bin_%{cfg.buildcfg}"
|
||||
|
||||
files {"**.cpp", "**.c", "**.h"}
|
||||
|
||||
filter "system:windows"
|
||||
entrypoint "WinMainCRTStartup"
|
||||
|
||||
filter "configurations:debug"
|
||||
defines {"DEBUG"}
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:release"
|
||||
defines {"NDEBUG"}
|
||||
optimize "On"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test1.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
printf("hello from test1 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test1();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#include "test2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void test2()
|
||||
{
|
||||
printf("hello from test2 !\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void test2();
|
||||
Loading…
Reference in New Issue