In learning purposes I've started to create my own game engine using C++, OpenGL 3.3, XAudio2 and some minor dependencies
The problems i reach are most commonly about structure of engine itself, like where does the App begins and Engine ends?
schemeengine.jpg
For now I have Engine project building into .lib, and Editor project building into .exe, that depends on Engine.lib and uses it:
projectlist.jpg

-----------------------------------

The problem is i need my Logic of App to react on events like Update, click on Button, how do i achieve that if Engine must be a built-ready alone app, not depending on my Logic.h, but Logic.h must react on events in Engine?

I thought about engineSetButtonPressCallback(void (*p)(...)), engineSetUpdateCallback(void (*p)()), but that seems wrong, like accessing not your own scope

So if Engine and App are 2 different entities, who can transport events from Engine to App? I prefer not to use OOP, so Engine is not a class, and App can't be like class App:Engine, so i could use virtual methods

-----------------------------------

main.cpp is like:
Code:
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	// Pre-init
	CoInitialize(0); // COM init
	std::ios::sync_with_stdio(false); // super fast io

	ResetCurrentDirectory();

	// Init

	swEngineInit();

	// 

	logicInit();
	
	// Run

	

	swEngineRun();

	// Release

	swEngineRelease();

	// Exit

	closelog();
	CoUninitialize();

	return 0; // end app
}
logic comes for smth like that:

Code:
#include "Logic.h"

// globals

bool bUILoaded = false;



// end globals

void preloadUI()
{
	std::ifstream input("UIList.txt", std::ios::in);
	char buffer[256]; string line;
	while(input.getline(buffer, 255))
	{
		line = buffer;
		if(line != "")
		{
			tpPreloadTexture(line, TEXTURE_TYPE_SHARP);
		}
	}

	input.close();
	
	bUILoaded = true;
}

void logicInit()
{
	tpPreloadTexture("Graphic/UI/LoadScreen.png", TEXTURE_TYPE_SHARP);
	uiSetBackground("Graphic/UI/LoadScreen.png");

	Sprite s;
	s.name = "test";
	s.relx = 0.5;
	s.rely = 0.5;
	s.posy = 60;
	s.width = 100;
	s.height = 60;
	s.texture = "Graphic/UI/ButtonStart.png";
	uiAddSprite(s);

	

	saDestroyOnEnd(saCreateSound("Sound/Arrow/arrwdth_02.ogg"));

	preloadUI();
}

void logicUpdate()
{
	
}

void logicSpritePress(string name)
{

}

void logicButtonPress(string name)
{

}
the main loop stuff hiden in engine:

Code:
void swEngineRun()
{
	printlog("message: entering win loop");
	waEventLoop();
}
winapi, depending highly on framework GLFW:

Code:
void waEventLoop()
{
	LARGE_INTEGER timeFrequency;
	LARGE_INTEGER timeNow;
	bool useQPC = QueryPerformanceFrequency(&timeFrequency);
	double prevTime = 0.0;

	if(useQPC)
	{
		QueryPerformanceCounter(&timeNow);
		dCreateTime = (1000LL * timeNow.QuadPart) / timeFrequency.QuadPart * 0.001;
	} else
		dCreateTime = GetTickCount() * 0.001;

	while(true)
	{
		glfwPollEvents();

		if(bErrorFlag)
		{
			printlog("message: fatal error in engine, closing win loop");
			break;
		}

		if(bExitFlag)
		{
			printlog("message: exit message recieved, closing win loop");
			break;
		}

		prevTime=dRealTime;

		if(useQPC)
		{
			QueryPerformanceCounter(&timeNow);
			dRealTime = (1000LL * timeNow.QuadPart) / timeFrequency.QuadPart * 0.001;
		} else
			dRealTime = GetTickCount() * 0.001;

		bPrevMouseLeft = glfwGetMouseButton(hWindow, GLFW_MOUSE_BUTTON_LEFT);
		bPrevMouseRight = glfwGetMouseButton(hWindow, GLFW_MOUSE_BUTTON_RIGHT);
		for(int i = 0; i < 512; i++)
		{
			bPrevKey[i] = glfwGetKey(hWindow, i);
		}

		if(dRealTime - dTime >= UPDATE_INTERVAL)
		{
			dTime += UPDATE_INTERVAL;
			if(dRealTime - dTime > UPDATE_INTERVAL * UPDATE_DEATH)
			{
				dTime = dRealTime - UPDATE_INTERVAL * UPDATE_DEATH;
			}

			// update

			swEngineUpdate();

			// errors

			if(saGetErrorFlag()) bErrorFlag = true;
			if(raGetErrorFlag()) bErrorFlag = true;

			glfwSwapBuffers(hWindow);
		}

		if(!glfwGetWindowAttrib(hWindow, GLFW_FOCUSED))
		{
			Sleep(2);
		}
	}
}
engine update is like:

Code:
void swEngineUpdate()
{
	// update

	uiUpdate();

	// render

	raRenderStart();

	uiRender();

	raRenderEnd();
}
--------------------------------------------

sorry for my crappy english, i hope u understood my question and can help me with the topic, im solving this question for a long time. also sorry for in-text attachments, can't find the spoiler button :/